package login

import (
	"cloud_android_backend/api/common"
	"cloud_android_backend/pkg/middleware/authorization/jwt"
	model "cloud_android_backend/pkg/models/users"
	"cloud_android_backend/pkg/modules/message"
	"cloud_android_backend/pkg/utils"
	"cloud_android_backend/pkg/utils/uuid"
	"context"
	"crypto/md5"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang/glog"
	"github.com/jinzhu/gorm"
	"math/rand"
	"modules.tenxcloud.com/common/composite"
	rb "modules.tenxcloud.com/common/middleware"
	"modules.tenxcloud.com/common/utility/errors"
	"modules.tenxcloud.com/common/utility/success"
	"regexp"
	"strconv"
	"time"
)

func Register(application *gin.RouterGroup) {

	application.POST("/login/send_message", rb.RequestBody, SendMessage)
	application.POST("/login/login", rb.RequestBody, Login)

	application.POST("/login/register", rb.RequestBody, LoginRegister)
}

func SendMessage(c *gin.Context) {
	var param struct {
		Phone string `json:"phone"`
	}
	body, _ := c.Get(rb.RequestBodyKey)
	if err := json.Unmarshal(body.([]byte), &param); err != nil {
		c.AbortWithStatusJSON(errors.BadRequest(err))
		return
	}
	if param.Phone == "" {
		c.AbortWithStatusJSON(common.ErrorResponse("手机号不能为空"))
		return
	}
	phonePattern := `^1[3-9]\d{9}$`
	// 编译正则表达式
	phoneRegex, err := regexp.Compile(phonePattern)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(fmt.Sprintf("internal err:%s", err.Error())))
		return
	}
	matched := phoneRegex.MatchString(param.Phone)
	if !matched {
		c.AbortWithStatusJSON(common.ErrorResponse("手机号输入有误"))
		return
	}
	redisCli := utils.GetRedis()
	history, err := redisCli.HGetAll(context.Background(), message.PhoneVerifyCodeCacheName).Result()
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(fmt.Sprintf("internal err:%s", err.Error())))
		return
	}
	if history["send_time"] != "" {
		lastSend, _ := strconv.ParseInt(history["send_time"], 10, 64)
		if time.Now().Unix()-lastSend < 60 { //上次发送时间小于60秒
			c.AbortWithStatusJSON(common.ErrorResponse("操作频繁，请稍后再试！"))
			return
		}
	}
	code := rand.Intn(900000) + 100000
	sms := message.NewAliSMS()
	err = sms.SendPhoneCode(param.Phone, strconv.Itoa(code))
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(fmt.Sprintf("短信发送失败！%s", err.Error())))
		return
	}
	fmt.Println("send code success", code)
	c.JSON(success.OK(common.SuccessResponse("")))
}

func Login(c *gin.Context) {

	var param struct {
		UserName  string `json:"username"`
		Phone     string `json:"phone"`
		Code      string `json:"code"`
		Password  string `json:"password"`
		LoginType string `json:"login_type"`
	}
	body, _ := c.Get(rb.RequestBodyKey)
	if err := json.Unmarshal(body.([]byte), &param); err != nil {
		c.AbortWithStatusJSON(errors.BadRequest(err))
		return
	}
	if param.LoginType != "phone" && param.LoginType != "password" {
		c.AbortWithStatusJSON(common.ErrorResponse("登录方式错误！"))
		return
	}
	lb := &jwt.LoginInfo{}
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	mu := model.New()
	if param.LoginType == "phone" {
		if param.Phone == "" || param.Code == "" {
			c.AbortWithStatusJSON(common.ErrorResponse("参数不能为空！"))
			return
		}
		if verify := message.VerifyPhoneCode(param.Phone, param.Code); !verify {
			c.AbortWithStatusJSON(common.ErrorResponse("验证码错误或已过期"))
			return
		}

		if err := mu.GetByPhone(db, param.Phone); err != nil {
			if gorm.IsRecordNotFoundError(err) { //记录不存在则添加
				mu.UserID = uuid.NewUserID()
				mu.UserName = "user" + strconv.Itoa(rand.Intn(9000000)+1000000)
				mu.RegistryTime = time.Now()
				mu.LastLoginTime = time.Now()
				mu.Phone = param.Phone
				err = mu.Create(db)
				if err != nil {
					c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
					return
				}

			} else {
				c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
				return
			}

		}
		lb.UserID = mu.UserID
		lb.Phone = mu.Phone
		lb.UserName = mu.UserName
	} else {
		if param.UserName == "" || param.Password == "" {
			c.AbortWithStatusJSON(common.ErrorResponse("参数不能为空！"))
			return
		}
		err = mu.GetByAccount(db, param.UserName)
		if err != nil {
			if err != nil {
				c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			}
		}
		pwd := fmt.Sprintf("%x", md5.Sum([]byte(param.Password)))
		if pwd != mu.Password {
			c.AbortWithStatusJSON(common.ErrorResponse("账号或密码错误！"))
			return
		}
		lb.UserID = mu.UserID
		lb.UserName = mu.UserName

	}
	//lb := &jwt.LoginInfo{}

	//balance, err := payment_utils.GetUserBalance(db, mu.UserID)
	//fmt.Printf("User balance: %.2f\n", balance)
	token, err := jwt.Authorize(lb)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	c.JSON(success.OK(common.SuccessResponse(token)))
	// c.JSON(success.OK(common.SuccessResponse(gin.H{
	// 	"token":   token,
	// 	"balance": balance,
	// })))
}

type RegisterParam struct {
	Phone           string `json:"phone"`
	Code            string `json:"code"`
	Password        string `json:"password"`
	PasswordConfirm string `json:"password_confirm"`
	UserName        string `json:"username"`
}

func LoginRegister(c *gin.Context) {
	var registerParam RegisterParam
	body, _ := c.Get(rb.RequestBodyKey)
	if err := json.Unmarshal(body.([]byte), &registerParam); err != nil {
		c.AbortWithStatusJSON(errors.BadRequest(err))
		return
	}
	if registerParam.Phone == "" || registerParam.Code == "" || registerParam.Password == "" || registerParam.PasswordConfirm == "" || registerParam.UserName == "" {
		c.AbortWithStatusJSON(common.ErrorResponse("参数不能为空！"))
		return
	}
	if registerParam.Password != registerParam.PasswordConfirm {
		c.AbortWithStatusJSON(common.ErrorResponse("密码不一致！"))
		return
	}
	if verify := message.VerifyPhoneCode(registerParam.Phone, registerParam.Code); !verify {
		c.AbortWithStatusJSON(common.ErrorResponse("验证码错误或已过期"))
		return
	}
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Error(err)
	}
	mu := model.New()
	if err := mu.GetByPhone(db, registerParam.Phone); err != nil {
		if !gorm.IsRecordNotFoundError(err) { //记录不存在则添加
			c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
			return
		}
	}
	if mu.UserID != "" {
		c.AbortWithStatusJSON(common.ErrorResponse("手机号已存在！"))
		return
	}
	err = mu.GetByAccount(db, registerParam.UserName)
	if err != nil && !gorm.IsRecordNotFoundError(err) {
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	if mu.UserID != "" {
		c.AbortWithStatusJSON(common.ErrorResponse("用户名已存在！"))
		return
	}
	mu.UserID = uuid.NewUserID()
	mu.Account = registerParam.UserName
	mu.UserName = registerParam.UserName
	mu.RegistryTime = time.Now()
	//mu.LastLoginTime = time.Now()
	mu.Phone = registerParam.Phone
	mu.Password = fmt.Sprintf("%x", md5.Sum([]byte(registerParam.Password)))
	err = mu.Create(db)
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	token, err := jwt.Authorize(&jwt.LoginInfo{
		UserID:   mu.UserID,
		UserName: mu.UserName,
		Phone:    mu.Phone,
	})
	if err != nil {
		c.AbortWithStatusJSON(common.ErrorResponse(err.Error()))
		return
	}
	c.JSON(success.OK(common.SuccessResponse(token)))
}
